<template>
  <el-upload
    v-show='mode === "edit"'
    v-model:file-list="fileList"
    :multiple='multiple'
    ref='uploadRef'
    :on-remove="handleRemove"
    :before-remove="beforeRemove"
    :on-exceed="handleExceed"
    :on-change="handleChange"
    :auto-upload='false'
    :http-request='httpRequest'
    v-bind="$attrs"
    style='width: 100%'
  >
    <el-button ref='upBtn' type="primary" size='small'>点击上传</el-button>
  </el-upload>
  <div v-show='mode === "detail"'>
    <div v-for='(item, index) in fileList' :key='index'>
      <el-link ref='downloadLinksRef' :href='item.url' type="primary">{{ item.name }}</el-link>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { UploadProps, UploadRequestOptions } from 'element-plus'
import { nextTick, ref, toRefs, useTemplateRef } from 'vue'
// import client from '@/utils/config/client'
// import { batchSave, batchRemove, getByObjectId, getByFileIds } from '@/api/sys/file'
import { addBatch, deleteBatch, getByObjectId, getById } from '@/api/file/file.ts'

const props = withDefaults(defineProps<{
  mode: 'edit' | 'detail',
  isRequired: boolean,
  multiple: boolean,
}>(), {
  mode: 'edit',
  isRequired: false,
  multiple: true
})

const {mode, isRequired, multiple } = toRefs(props)

const uploadRef = useTemplateRef('uploadRef')

// oss文件上传列表
// const ossFile = ref<any[]>([])
// 删除文件列表
const removeObjects = ref<any[]>([])
// {
//   fileId: '123123',
//   name: 'element-plus-logo.svg',
//   url: 'https://element-plus.org/images/element-plus-logo.svg'
// }
const fileList = ref<any[]>([])
const allFileList = ref<any[]>([])
const downloadLinksRef = ref()
const upBtn = ref()
// eslint-disable-next-line no-unused-vars
const emits = defineEmits(['fileChange'])
// 手动调用上传事件
const httpRequest = (options: UploadRequestOptions) => {
  // console.log('options', options)
  const objectName = getObjectName(options.file.name)
  // ossFile.value.push({
  //   rowFile: options.file,
  //   objectName
  // })
}
// 混淆上传的文件名
const getObjectName = (fileName) => {
  return (new Date().getTime().toString() + Math.floor(Math.random() * 10000).toString()).split('').reverse().join('') + '.' + fileName.split('.').pop()
}
// 文件移除事件
const handleRemove: UploadProps['onRemove'] = (file:any, uploadFiles) => {
  // console.log('remove', file, uploadFiles)
  if (file.fileId) {
    // 如果存在file id 则表示从后台获取的file对象，需要记录delete list
    removeObjects.value.push({ fileId: file.fileId, objectName: file.objectName })
  }
  allFileList.value = uploadFiles
  emits('fileChange', 'remove', allFileList.value.length > 0, file.name)
}
const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
  // failNotify('超出文件上传数')
}
const beforeRemove : UploadProps['beforeRemove'] = (uploadFile, uploadFiles) => {
  return confirm(`确认要移除 ${uploadFile.name} 该文件吗`).then(
    () => true,
    () => false
  )
}
const handleChange: UploadProps['onChange'] = (uploadFile, uploadFiles) => {
  // console.log('files, 11111', uploadFile)
  emits('fileChange', 'add', uploadFiles.length > 0, uploadFile.name)
  allFileList.value = uploadFiles
}
// 手动调用上传
const upload = async() => {
  ossFile.value = []
  const uploads: any[] = []
  await uploadRef.value.submit()
  // 上传oss
  if (ossFile.value.length > 0) {
    // 创建上传文件的promise，放入promise队列
    for (let i = 0; i < ossFile.value.length; i++) {
      uploads.push(client.put(ossFile.value[i].objectName, ossFile.value[i].rowFile))
    }
    await Promise.all(uploads)
  }
  // 删除文件
  if (removeObjects.value.length > 0) {
    await batchRemove(removeObjects.value.map(e => e.fileId))
    for (let i = 0; i < removeObjects.value.length; i++) {
      await client.delete(removeObjects.value[i].objectName)
    }
  }
  // 新增文件
  let saveIds = []
  if (ossFile.value.length > 0) {
    const sysFile: any[] = []
    for (let i = 0; i < ossFile.value.length; i++) {
      sysFile.push({
        fileName: ossFile.value[i].rowFile.name,
        fileType: ossFile.value[i].rowFile.name.split('.').pop(),
        fileSize: ossFile.value[i].rowFile.size,
        filePath: ossFile.value[i].objectName,
        serverType: 'oss'
      })
    }
    const res = await batchSave(sysFile)
    saveIds = res.data
  }
  // 返回文件id
  return Promise.resolve(fileList.value.map((e: any) => e.fileId).concat(saveIds).filter(f => f && true))
}
const init = (objectId, targetType) => {
  clean()
  nextTick(() => {
    clean()
    if (!objectId) {
      return
    }
    if (targetType === 'node') {
      getByFileIds(objectId).then(res => {
        if (res.data.length > 0) {
          render(res.data)
        }
      })
    } else {
      getByObjectId(objectId).then(res => {
        if (res.data.length > 0) {
          render(res.data)
        }
      })
    }
  })
}
const render = (files) => {
  files.forEach(e => {
    const response = {
      'content-disposition': `attachment; filename=${encodeURIComponent(e.fileName)}`
    }
    const url = client.signatureUrl(e.filePath, { response })
    fileList.value.push({
      fileId: e.id,
      objectName: e.filePath,
      name: e.fileName,
      url
    })
  })
  if (files && files.length > 0) {
    allFileList.value = fileList.value
    emits('fileChange', 'load', true, '')
  }
}
const clean = () => {
  ossFile.value = []
  removeObjects.value = []
  fileList.value = []
}
const validate = async() => {
  if (isRequired?.value) {
    await uploadRef.value.submit()
    if (ossFile.value.length > 0 || fileList.value.length > 0) {
      // 验证完成后，上传列表清空
      ossFile.value = []
      return Promise.resolve(true)
    } else {
      // 验证完成后，上传列表清空
      ossFile.value = []
      return Promise.resolve(false)
    }
  } else {
    return Promise.resolve(true)
  }
}
const startUpload = () => {
  upBtn.value.$el.click()
}
const removeAllFile = () => {
  if (allFileList.value.length > 0) {
    for (let i = 0; i < allFileList.value.length; i++) {
      uploadRef.value.handleRemove(allFileList.value[i])
    }
  }
}
const handleDownload = () => {
  // 默认下载第一个附件
  if (downloadLinksRef.value) {
    if (Array.isArray(downloadLinksRef.value)) {
      downloadLinksRef.value[0].$el.click()
    } else {
      downloadLinksRef.value.$el.click()
    }
  }
}
defineExpose({
  upload,
  init,
  clean,
  validate,
  startUpload,
  removeAllFile,
  handleDownload
})
</script>

<style scoped>

</style>